package me.zhengjie.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import me.zhengjie.dao.*;
import me.zhengjie.utils.*;
import me.zhengjie.vo.MaterialVo;
import me.zhengjie.mapper.*;
import me.zhengjie.server.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @author xinglin.lu
* @description 针对表【iws_outbound_order(出库单)】的数据库操作Service实现
* @createDate 2025-06-10 08:54:56
*/
@Service
@AllArgsConstructor
public class OutboundOrderServiceImpl extends ServiceImpl<OutboundOrderMapper, OutboundOrder>
    implements OutboundOrderService {
    private final RedisUtils redisUtils;

    private final   OutboundOrderHistoryMapper outboundOrderHistoryMapper;

    private final OutboundOrderDetailMapper outboundOrderDetailMapper;

    private final TransferOutboundDetailMapper   transferOutboundDetailMapper;

    private final FloorMinMaxService floorMinMaxService;

    private final MaterialMapper materialMapper;

    private final MaterialService materialService;

    private final OutBoundTaskMapper outBoundTaskMapper;

    private final MaterialDetailService materialDetailService;

    private final OutBoundTaskService outBoundTaskService;

    private final SortingService sortingService;

    private final ContainerService containerService;

    private final StoreLocalService storeLocalService;

    @Override
    public PageResult<OutboundOrder> queryAll(OutboundOrder criteria) {
        List<OutboundOrder> all = baseMapper.selectForList(criteria);
        List<OutboundOrder> paging = new ArrayList<>();
        if (all!=null&&all.size()>0){
            paging = PageUtil.paging(criteria.getPage()-1, criteria.getSize(), all);
        }
        return PageUtil.toPage(paging,all);
    }

    @Override
    public PageResult<OutboundOrder> queryAll(OutboundOrder criteria, Page<Object> page) {
        return PageUtil.toPage(baseMapper.findAll(criteria, page));
    }

    @Override
    public void download(List<OutboundOrder> outboundOrders, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (OutboundOrder outBoundOrder : outboundOrders) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("出库单编号", outBoundOrder.getOutboundOrderNo());
            map.put("出库单状态", outBoundOrder.getStatus());
            map.put("出库单类型", outBoundOrder.getStatus());
            map.put("创建时间", outBoundOrder.getCreateTime());
            map.put("出库时间（可以为空）", outBoundOrder.getOutboundTime());
            map.put("结束时间（可以为空）", outBoundOrder.getFinishTime());
            map.put("创建人", outBoundOrder.getCreateName());
            map.put("修改人（可以为空）", outBoundOrder.getUpdateName());
            map.put("出库策略", outBoundOrder.getOutboundPolicy());
            map.put("出库货物类型", outBoundOrder.getOutboundType());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
    //建立出库单
    @Override
    public int addOutboundOrder(@RequestBody OutboundOrder resources){
        String currentUsername ="System";
        try {
            currentUsername = SecurityUtils.getCurrentUsername();
        } catch (Exception e) {
        }
        redisUtils.del(currentUsername);
        Long increment = redisUtils.increment(currentUsername);
        if (increment > 3){
            throw new RuntimeException("您今日建单已超过3单，请明天再试");
        }

        if (resources.getTransDaoList().isEmpty()){
            throw new RuntimeException("新增的数据不能为空");
        }
        ArrayList<OutboundOrderDetailDao> items = new ArrayList<>();
        ArrayList<MaterialDetailDao> materialDetailDaos = new ArrayList<>();
        ArrayList<MaterialDetailDao> materialDetailDaosForFloor1 = new ArrayList<>();
        ArrayList<MaterialDetailDao> materialDetailDaosForFloor2 = new ArrayList<>();
        List<String> strings = new ArrayList<>();
        Double totalOutWeight=0.00;
        String floor=null;
        //前端传过来的汇总数据
        List<TransDao> transDaoList = resources.getTransDaoList();
        HashMap<String,Double> hashMap = new HashMap<>();
        List<String>  orderList = new ArrayList<>();
        List<String>  orderOtherList = new ArrayList<>();
        String floor1 = "M1";
        String floor2 = "M2";
        HashMap<String,Double> totalMap = new HashMap<>();
        for (TransDao transDao : transDaoList) {
            String materialCode = transDao.getMaterialCode();//物料号
            //该物料的库存
            Double inventoryQuantity = getInventoryQuantity(materialCode);
            if (inventoryQuantity==null){
                throw new RuntimeException("物料没有库存！");
            }
            if(transDao.getWeight()>inventoryQuantity||transDao.getWeight()>transDao.getNeedWeight()){
                throw new RuntimeException("需求数量不能大于可发数量/需求数量不能大于库存");
            }
            hashMap.put(transDao.getMaterialCode(),transDao.getWeight());
            Double weight = transDao.getWeight();//需求数量
            totalOutWeight+=weight;
            List<String> transferList = transDao.getTransferList();//调拨单号
            for (int i = 0; i < transferList.size(); i++) {
                strings.add(transferList.get(i));
                MaterialDetailDao materialDetailDao = materialDetailService.getOne(new LambdaQueryWrapper<MaterialDetailDao>()
                        .eq(MaterialDetailDao::getTransferId, transferList.get(i)).eq(MaterialDetailDao::getMaterialCode, materialCode));
                floor=materialDetailDao.getTargetLocation();
                if(materialDetailDao==null){
                    throw new RuntimeException("调拨单号不存在/物料编号不存在");
                }
                //回填调拨单数据
                weight-=materialDetailDao.getUnIssuedWeight();
                if (weight>0){
                    materialDetailDao.setUnIssuedWeight(0.00);
                    materialDetailDao.setIssuedWeight(materialDetailDao.getMaterialNum());
                }else {
                    materialDetailDao.setUnIssuedWeight(materialDetailDao.getUnIssuedWeight()-(materialDetailDao.getUnIssuedWeight()+weight));
                    System.out.println(materialDetailDao.getUnIssuedWeight()-(materialDetailDao.getUnIssuedWeight()+weight)+"****1");
                    materialDetailDao.setIssuedWeight(materialDetailDao.getMaterialNum()-materialDetailDao.getIssuedWeight());
                }
                materialDetailService.updateById(materialDetailDao);
                materialDetailDaos.add(materialDetailDao);
            }
            List<String> boxList = new ArrayList<>();
            if (transDao.getWeight()>30){
                List<LockMatDao>  lockMatDao1 =  materialMapper.selectForList(transDao.getMaterialCode(),floor1);
                //大于30的先出一楼看一楼最大起订量
                    for (LockMatDao lockMatDao : lockMatDao1) {
//                        hashMap =getTotalNum(lockMatDao1,hashMap);
                        if (hashMap.get(lockMatDao.getMat())>=transDao.getWeight()){
                            boxList.add(lockMatDao.getContainer());
                            totalMap.put(floor1,lockMatDao.getWeight());
                            hashMap.put(lockMatDao.getMat(),hashMap.get(lockMatDao.getMat())-lockMatDao.getWeight());
                        }else {
                            break;
                        }
                        transDaoList.stream().filter(e->e.getMaterialCode().equals(materialCode)).map(TransDao::getTransferList).collect(Collectors.toList()).forEach(e->{
                            for (String s : e) {
                                MaterialDetailDao materialDetailDao = materialDetailService.getOne(new LambdaQueryWrapper<MaterialDetailDao>()
                                        .eq(MaterialDetailDao::getTransferId,s).eq(MaterialDetailDao::getMaterialCode, materialCode));
                                materialDetailDaosForFloor1.add(materialDetailDao);
                            }
                        });
                    }
                orderList = getOrderList(resources,orderList,transDao);
                if (hashMap.get(transDao.getMaterialCode())<=0){
                    break;
                }
                transDaoList.stream().filter(e->e.getMaterialCode().equals(materialCode)).map(TransDao::getTransferList).collect(Collectors.toList()).forEach(e->{
                    for (String s : e) {
                        MaterialDetailDao materialDetailDao = materialDetailService.getOne(new LambdaQueryWrapper<MaterialDetailDao>()
                                .eq(MaterialDetailDao::getTransferId,s).eq(MaterialDetailDao::getMaterialCode, materialCode));
                        materialDetailDaosForFloor2.add(materialDetailDao);
                    }
                });
                orderOtherList = getOrderList(resources,orderOtherList,transDao);
                List<LockMatDao>  lockMatDao2 =  materialMapper.selectForList(transDao.getMaterialCode(),floor2);
                for (LockMatDao lockMatDao : lockMatDao2) {
//                        hashMap =getTotalNum(lockMatDao1,hashMap);
                    if (hashMap.get(lockMatDao.getMat())>=transDao.getWeight()){
                        boxList.add(lockMatDao.getContainer());
                        totalMap.put(floor2,lockMatDao.getWeight());
                        hashMap.put(lockMatDao.getMat(),hashMap.get(lockMatDao.getMat())-lockMatDao.getWeight());
                    }else {
                        break;
                    }
                }
            }else {
                List<LockMatDao>  lockMatDao2 =  materialMapper.selectForList(transDao.getMaterialCode(),floor2);
                for (LockMatDao lockMatDao : lockMatDao2) {
                    if (hashMap.get(lockMatDao.getMat())>=transDao.getWeight()){
                        boxList.add(lockMatDao.getContainer());
                        totalMap.put(floor2,lockMatDao.getWeight());
                        hashMap.put(lockMatDao.getMat(),hashMap.get(lockMatDao.getMat())-lockMatDao.getWeight());
                    }else {
                        break;
                    }
                }
                transDaoList.stream().filter(e->e.getMaterialCode().equals(materialCode)).map(TransDao::getTransferList).collect(Collectors.toList()).forEach(e->{
                    for (String s : e) {
                        MaterialDetailDao materialDetailDao = materialDetailService.getOne(new LambdaQueryWrapper<MaterialDetailDao>()
                                .eq(MaterialDetailDao::getTransferId,s).eq(MaterialDetailDao::getMaterialCode, materialCode));
                        materialDetailDaosForFloor2.add(materialDetailDao);
                    }
                });
                orderOtherList = getOrderList(resources,orderOtherList,transDao);
                if (hashMap.get(transDao.getMaterialCode())<=0){
                    break;
                }
                transDaoList.stream().filter(e->e.getMaterialCode().equals(materialCode)).map(TransDao::getTransferList).collect(Collectors.toList()).forEach(e->{
                    for (String s : e) {
                        MaterialDetailDao materialDetailDao = materialDetailService.getOne(new LambdaQueryWrapper<MaterialDetailDao>()
                                .eq(MaterialDetailDao::getTransferId,s).eq(MaterialDetailDao::getMaterialCode, materialCode));
                        materialDetailDaosForFloor1.add(materialDetailDao);
                    }
                });
                orderList = getOrderList(resources,orderList,transDao);
                List<LockMatDao>  lockMatDao1 =  materialMapper.selectForList(transDao.getMaterialCode(),floor1);
                //大于30的先出一楼看一楼最大起订量
                for (LockMatDao lockMatDao : lockMatDao1) {
                    if (hashMap.get(lockMatDao.getMat())>=transDao.getWeight()){
                        boxList.add(lockMatDao.getContainer());
                        totalMap.put(floor1,lockMatDao.getWeight());
                        hashMap.put(lockMatDao.getMat(),hashMap.get(lockMatDao.getMat())-lockMatDao.getWeight());
                    }else {
                        break;
                    }
                }
            }
        }
        //判断一二楼是否符合起订量
        ifNotNumForFloor(resources,totalMap,floor2);
        ifNotNumForFloor(resources,totalMap,floor1);
        //判断预约时间是否超过24小时
        if (resources.getRequireTime()!=null) {
            // 计算时间差（毫秒）
            long diffInMillis = Math.abs(new Date().getTime() - resources.getRequireTime().getTime());
            // 转换为小时并判断是否超过24小时
            long diffInHours = diffInMillis / (1000 * 60 * 60);
            if (diffInHours> 24){
                throw new RuntimeException("预约时间不能超过1天");
            }
        }
        if (totalMap.get(floor1)!=null&&totalMap.get(floor2)!=null&&totalMap.get(floor1)>0&&totalMap.get(floor2)>0){
            /*
            1 根据楼层分解出库单
            2 回填出库单表
            3 一楼
            */
            OutboundOrder outboundOrder = new OutboundOrder();
            outboundOrder.setOutboundOrderNo("OUT_" + getCurrentDate());
            outboundOrder.setStatus(0);
            outboundOrder.setCreateTime(new Date());
            outboundOrder.setCreateName("admin");
            outboundOrder.setOutboundStore(resources.getOutboundStore());
            outboundOrder.setRequireTime(resources.getRequireTime());
            outboundOrder.setDestination(resources.getDestination());
            outboundOrder.setOutboundPolicy(resources.getOutboundPolicy());
            //添加出库详情表
            for (MaterialDetailDao materialVo : materialDetailDaosForFloor1) {
                String materialCode = materialVo.getMaterialCode();
                OutboundOrderDetailDao outBoundOrderDetailDao = getOutBoundOrderDetail(materialVo, outboundOrder);
                //锁库存
                Double material=materialMapper.selectList(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, materialCode))
                        .stream().mapToDouble(MaterialDao::getInventoryQuantity) // 提取 inventoryQuantity 字段
                        .sum();
//            materialService.updateInventory(material,materialVo.getUnIssuedWeight());
                items.add(outBoundOrderDetailDao);
            }
            //添加出库调拨单中间表
            for (String item : orderList) {
                TransferOutboundDetailDao transferOutboundDetailDao = getTransferOrderDetail(item,outboundOrder);
                transferOutboundDetailMapper.insert(transferOutboundDetailDao);
            }
            baseMapper.insert(outboundOrder);
            /*
            1 根据二楼所有出的出库单
            2 关联所出物料的调拨单
            */
            outboundOrder.setOutboundOrderNo("OUT_" + getCurrentDate());
            //添加出库详情表
            for (MaterialDetailDao materialVo : materialDetailDaosForFloor2) {
                String materialCode = materialVo.getMaterialCode();
                OutboundOrderDetailDao outBoundOrderDetailDao = getOutBoundOrderDetail(materialVo, outboundOrder);
                //锁库存
                Double material=materialMapper.selectList(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, materialCode))
                        .stream().mapToDouble(MaterialDao::getInventoryQuantity) // 提取 inventoryQuantity 字段
                        .sum();
//            materialService.updateInventory(material,materialVo.getUnIssuedWeight());
                items.add(outBoundOrderDetailDao);
            }
            //添加出库调拨单中间表
            for (String item : orderOtherList) {
                TransferOutboundDetailDao transferOutboundDetailDao = getTransferOrderDetail(item,outboundOrder);
                transferOutboundDetailMapper.insert(transferOutboundDetailDao);
            }
            baseMapper.insert(outboundOrder);

        }else {
            //创建出库单
            OutboundOrder outboundOrder = new OutboundOrder();
            outboundOrder.setOutboundOrderNo("OUT_" + getCurrentDate());
            outboundOrder.setStatus(0);
            outboundOrder.setCreateTime(new Date());
            outboundOrder.setCreateName("admin");
            outboundOrder.setOutboundStore(resources.getOutboundStore());
            outboundOrder.setRequireTime(resources.getRequireTime());
            outboundOrder.setDestination(resources.getDestination());
            outboundOrder.setOutboundPolicy(resources.getOutboundPolicy());
            //添加出库详情表
            for (MaterialDetailDao materialVo : materialDetailDaos) {
                String materialCode = materialVo.getMaterialCode();
                OutboundOrderDetailDao outBoundOrderDetailDao = getOutBoundOrderDetail(materialVo, outboundOrder);
                //锁库存
                Double material=materialMapper.selectList(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, materialCode))
                        .stream().mapToDouble(MaterialDao::getInventoryQuantity) // 提取 inventoryQuantity 字段
                        .sum();
//            materialService.updateInventory(material,materialVo.getUnIssuedWeight());
                items.add(outBoundOrderDetailDao);
            }
            //添加出库调拨单中间表
            for (String item : strings) {
                TransferOutboundDetailDao transferOutboundDetailDao = getTransferOrderDetail(item,outboundOrder);
                transferOutboundDetailMapper.insert(transferOutboundDetailDao);
            }
            baseMapper.insert(outboundOrder);
        }
        int i = outboundOrderDetailMapper.batchInsertOutBoundOrderDetails(items);
        return i;
    }

    private List<String> getOrderList(OutboundOrder resources, List<String> orderList, TransDao transDao) {
        resources.getTransDaoList().stream().forEach(e-> {
            if (e.getMaterialCode().equals(transDao.getMaterialCode())){
                orderList.addAll(e.getTransferList());
            }
        });
        return orderList;
    }

    private void ifNotNumForFloor(OutboundOrder resources, HashMap<String, Double> hashMap, String floor) {
        FloorMinMaxDao floorMinMaxDao = floorMinMaxService.getOne(new LambdaQueryWrapper<FloorMinMaxDao>().eq(FloorMinMaxDao::getFloorId, floor));
        if (floorMinMaxDao == null) {
            throw new RuntimeException("未找到对应的楼层最小最大重量配置");
        }
        if (hashMap.get(floor)!=null){
            if (resources.getOutboundType().equals("原物料")&&hashMap.get(floor)> floorMinMaxDao.getMinWeight()||hashMap.get(floor)< floorMinMaxDao.getMaxWeight()){
                System.out.println("需要审批");
//                throw new RuntimeException("需要审批");
                //           approval();
            }else {
                throw new RuntimeException("不满足起订量需求");
            }
        }
    }

    private void ifNotNum(OutboundOrder resources,  HashMap<String,Double> hashMap,String floor) {
        FloorMinMaxDao floorMinMaxDao = floorMinMaxService.getOne(new LambdaQueryWrapper<FloorMinMaxDao>().eq(FloorMinMaxDao::getFloorId, floor));
        if (floorMinMaxDao == null) {
            throw new RuntimeException("未找到对应的楼层最小最大重量配置");
        }
        if (resources.getOutboundType().equals("原物料")&&hashMap.get(floor)> floorMinMaxDao.getMinWeight()||hashMap.get(floor)< floorMinMaxDao.getMaxWeight()){
            System.out.println("需要审批");
            //           approval();
        }else {
            throw new RuntimeException("不满足起订量需求");
        }
    }


    //开始出库并按物料分任务
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OutboundOrderDao outboundJob(String outboundOrderNo) throws InterruptedException, UnknownHostException {
        int totalContainer=0;
        int sortedContainer=0;
        int notSortedContainer=0;
        OutboundOrderDao outboundOrderDao = new OutboundOrderDao();
        List<MaterialSort> materialSorts = new ArrayList<MaterialSort>();
        OutboundOrder outboundOrder = baseMapper.selectOne(new LambdaQueryWrapper<OutboundOrder>().eq(OutboundOrder::getOutboundOrderNo, outboundOrderNo));
        outboundOrder.setOutboundTime(new Date());
        outboundOrder.setStartName(SecurityUtils.getCurrentUsername());
        List<OutBoundTaskDao> taskDaoList = outBoundTaskService.list(new LambdaQueryWrapper<OutBoundTaskDao>().eq(OutBoundTaskDao::getProductOutBoundOrderNo, outboundOrderNo));
        if (!taskDaoList.isEmpty()){
            //根据出库单号查找任务
            List<OutBoundTaskDao> outBoundTaskDaoList = outBoundTaskMapper.selectList(new LambdaQueryWrapper<OutBoundTaskDao>().eq(OutBoundTaskDao::getProductOutBoundOrderNo, outboundOrderNo));
            for (OutBoundTaskDao outBoundTaskDao : outBoundTaskDaoList) {
                //根据任务编码找到载具
                List<SortingDao> list = sortingService.list(new LambdaQueryWrapper<SortingDao>().eq(SortingDao::getOutboundTaskCode, outBoundTaskDaoList.get(0).getCode()));
                long count = list.stream().filter(e -> e.getOutboundTaskCode().equals(outBoundTaskDao.getCode())).count();
                totalContainer += (int) count;
                long countsorting = list.stream().filter(e -> e.getOutboundTaskCode().equals(outBoundTaskDao.getCode()) && e.getStatus() == 0).count();
                sortedContainer += (int) countsorting;
                long countnot = list.stream().filter(e -> e.getOutboundTaskCode().equals(outBoundTaskDao.getCode()) && e.getStatus() == 1).count();
                notSortedContainer += (int) countnot;
            }
            for (OutBoundTaskDao outBoundTaskDao : taskDaoList) {
                MaterialSort materialSort = new MaterialSort();
                materialSort.setMaterialCode(outBoundTaskDao.getMaterialCode());
                materialSort.setMaterialName(materialService.list(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, outBoundTaskDao.getMaterialCode())).get(0).getMaterialName());
                materialSort.setDemand(outBoundTaskDao.getMaterilaNweight());
                materialSort.setPicked(outBoundTaskDao.getSorted());
                materialSort.setDifference(outBoundTaskDao.getMaterilaNweight()-outBoundTaskDao.getSorted());
                materialSort.setInventory(materialService.list(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, outBoundTaskDao.getMaterialCode())).get(0).getInventoryQuantity());
                materialSorts.add(materialSort);
            }
            outboundOrderDao.setTotalContainer(totalContainer);
            outboundOrderDao.setSortedContainer(sortedContainer);
            outboundOrderDao.setNotSortedContainer(notSortedContainer);
            outboundOrderDao.setOutboundOrder(outboundOrder);
            outboundOrderDao.setMaterialSortList(materialSorts);
            return outboundOrderDao;
        }
        baseMapper.updateById(outboundOrder);
        List<OutboundOrderDetailDao> materialVoList = outboundOrderDetailMapper.selectList(new LambdaQueryWrapper<OutboundOrderDetailDao>().eq(OutboundOrderDetailDao::getIwsOutboundOrderId, outboundOrderNo));
        String hostAddress = InetAddress.getLocalHost().getHostAddress();
        outboundOrder.setWorkSpace(hostAddress);
        for (OutboundOrderDetailDao materialVo : materialVoList) {
            MaterialDao material = new MaterialDao();
            List<MaterialDao> materialDaos = materialMapper.selectList(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, materialVo.getMaterialCode()));
            if (materialDaos==null||materialDaos.size()<=0){
              throw new RuntimeException("物料编号不存在");
            }
            material = materialDaos.stream().findFirst().get();
            OutBoundTaskDao outBoundTaskDao = new OutBoundTaskDao();
            String uuid = UUID.randomUUID().toString().replace("-", "");
            outBoundTaskDao.setCode("TASK" + getCurrentDate()+uuid.substring(0, 8));
            outBoundTaskDao.setProductOutBoundOrderNo(outboundOrder.getOutboundOrderNo());
            outBoundTaskDao.setCreateTime(new Date());
            outBoundTaskDao.setCreateName("");
            outBoundTaskDao.setStatus(0);
            outBoundTaskDao.setMaterialCode(material.getMaterialCode());
            outBoundTaskDao.setOutboundType(material.getMaterialCategory());
            outBoundTaskDao.setOutboundPolicy(outboundOrder.getOutboundPolicy());
            outBoundTaskDao.setMaterilaNweight(materialVo.getWeight());
            outBoundTaskDao.setOutWarehouse(outboundOrder.getOutboundStore());
            outBoundTaskDao.setSorted(0.00);
            //手工
            if (outboundOrder.getOutboundPolicy()==0){
                outBoundTaskDao.setPriority(0);
            }else if(outboundOrder.getOutboundPolicy()==1){ //紧急
                outBoundTaskDao.setPriority(1);
            }else if(outboundOrder.getOutboundPolicy()==2){ //预约
                outBoundTaskDao.setPriority(2);
                outBoundTaskDao.setRequireTime(outboundOrder.getRequireTime());
            }else {
                outBoundTaskDao.setPriority(3);
            }
            outBoundTaskMapper.insert(outBoundTaskDao);
            outBoundTaskService.startOutBoundTask(outBoundTaskDao);
        }
        outboundOrder.setStatus(1);
        baseMapper.updateById(outboundOrder);

        outboundOrderDao.setOutboundOrder(outboundOrder);
        //根据出库单号查找任务
        List<OutBoundTaskDao> outBoundTaskDaoList = outBoundTaskMapper.selectList(new LambdaQueryWrapper<OutBoundTaskDao>().eq(OutBoundTaskDao::getProductOutBoundOrderNo, outboundOrderNo));
        for (OutBoundTaskDao outBoundTaskDao : outBoundTaskDaoList) {
            //根据任务编码找到载具
            List<SortingDao> list = sortingService.list(new LambdaQueryWrapper<SortingDao>().eq(SortingDao::getOutboundTaskCode, outBoundTaskDaoList.get(0).getCode()));
            long count = list.stream().filter(e -> e.getOutboundTaskCode().equals(outBoundTaskDao.getCode())).count();
            totalContainer+=(int) count;
            long countsorting = list.stream().filter(e -> e.getOutboundTaskCode().equals(outBoundTaskDao.getCode())&&e.getStatus()==0).count();
            sortedContainer+=(int) countsorting;
            long countnot = list.stream().filter(e -> e.getOutboundTaskCode().equals(outBoundTaskDao.getCode())&&e.getStatus()==1).count();
            notSortedContainer+=(int) countnot;
            MaterialSort materialSort = new MaterialSort();
            materialSort.setMaterialCode(outBoundTaskDao.getMaterialCode());
            materialSort.setMaterialName(materialService.list(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, outBoundTaskDao.getMaterialCode())).get(0).getMaterialName());
            materialSort.setDemand(outBoundTaskDao.getMaterilaNweight());
            materialSort.setPicked(outBoundTaskDao.getSorted());
            materialSort.setDifference(outBoundTaskDao.getMaterilaNweight()-outBoundTaskDao.getSorted());
            materialSort.setInventory(materialService.list(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, outBoundTaskDao.getMaterialCode())).get(0).getInventoryQuantity());
            materialSorts.add(materialSort);
        }
        outboundOrderDao.setTotalContainer(totalContainer);
        outboundOrderDao.setSortedContainer(sortedContainer);
        outboundOrderDao.setNotSortedContainer(notSortedContainer);
        outboundOrderDao.setMaterialSortList(materialSorts);
        return outboundOrderDao;
    }

    @Override
    public List<String> exitOutboudOrder() {
        List<String> materialCode= outBoundTaskMapper.exitOntBoundTask();
        return materialCode;
    }

    @Override
    public ComputeDao computeWeight(List<TransDao> transDaos) {
        ComputeDao computeDao = new ComputeDao();
//        Double sum= 0.0;
//        Double Monesum= 0.0;
//        Double Mtwosum= 0.0;
//        FloorMinMaxDao minMaxDaoM1=floorMinMaxService.getOne(new LambdaQueryWrapper<FloorMinMaxDao>().eq(FloorMinMaxDao::getFloorId, "M1"));
//        FloorMinMaxDao minMaxDaoM2=floorMinMaxService.getOne(new LambdaQueryWrapper<FloorMinMaxDao>().eq(FloorMinMaxDao::getFloorId, "M2"));
//        for (TransDao transDao : transDaos) {
//            sum+=transDao.getWeight();
//            if(transDao.getWeight()>30&&transDao.getWeight()<minMaxDaoM1.getMaxWeight()){
//                //大于30的先出一楼看一楼最大起订量
//                Monesum+=transDao.getWeight();
//                BymaterialCodeGetFloor();
//            } else if () {
//
//            }
//        }
//        if (sum<minMaxDaoM1.getMinWeight()||sum<minMaxDaoM2.getMinWeight()){
//            System.out.println("不足起订量，请重新输入");
//        }
//        computeDao.setSum(sum);
        return computeDao;
    }

    @Override
    public PageResult<OutboundOrderHistory> getOutOrderHistory(OutboundOrderHistory param) {
        List<OutboundOrderHistory> outboundOrderHistories = outboundOrderHistoryMapper.selectList(null);
        List<OutboundOrderHistory> paging = PageUtil.paging(param.getPage() - 1, param.getSize(), outboundOrderHistories);
        PageResult<OutboundOrderHistory> page = PageUtil.toPage(paging);
        return page;
    }

    @Override
    public PageResult<OutboundOrderDetailDao> getOutOrderHistoryDetail(  OutOrderHistoryDetailDao dao) {
        List<OutboundOrderDetailDao> outboundOrderDetailDaos = outboundOrderDetailMapper.selectList(new LambdaQueryWrapper<OutboundOrderDetailDao>().eq(OutboundOrderDetailDao::getIwsOutboundOrderId, dao.getCode()));
        List<OutboundOrderDetailDao> paging = PageUtil.paging(dao.getPage() - 1, dao.getSize(), outboundOrderDetailDaos);
        PageResult<OutboundOrderDetailDao> page = PageUtil.toPage(paging);
        return page;
    }

    @Override
    public PageResult<MaterialDao> noMaterials(NoMaterialsDao param) {
        List<MaterialDao> list = materialMapper.selectListForNo(param);
        if (list==null){
            return PageUtil.toPage(new ArrayList<>());
        }
        for (MaterialDao materialDao : list) {
            List<String>  orderList = materialMapper.selectOrderList(materialDao.getMaterialCode());
            List<String>  orderOtherList = materialMapper.selectBatchList(materialDao.getMaterialCode());
            materialDao.setBatchCode(orderList.toString().replace("[","").replace("]",""));
            materialDao.setPurchaseOrder(orderOtherList.toString().replace("[","").replace("]",""));
        }
        Integer total  = materialMapper.selectCoount();
        return PageUtil.toPage(list,total);
    }

    @Override
    public int handiwork(HandiWorkDao handiWorkDao) {
        List<String> containerIds = handiWorkDao.getContainerIds();
        //锁库存
        for (String containerId : containerIds) {
            ContainerDao containerDao = containerService.getOne(new LambdaQueryWrapper<ContainerDao>().eq(ContainerDao::getId, containerId));
            containerDao.setIonLock(1);
            containerService.updateById(containerDao);
        }
        OutboundOrder outboundOrder = new OutboundOrder();
        outboundOrder.setOutboundOrderNo("OUT_" + getCurrentDate());
        outboundOrder.setStatus(0);
        outboundOrder.setCreateTime(new Date());
        outboundOrder.setCreateName("admin");
        if (handiWorkDao.getDestination().equals(0)){
            outboundOrder.setDestination("分拣区");
        }else {
            outboundOrder.setDestination("抽检区");
        }
        outboundOrder.setOutboundPolicy(handiWorkDao.getType());
        return baseMapper.insert(outboundOrder);
    }

    @Override
    public int notOutBoundOrder(OutboundOrder resources) {
        List<TransDao> transDaoList = resources.getTransDaoList();
        OutboundOrder outboundOrder = new OutboundOrder();
        outboundOrder.setOutboundOrderNo("OUT_" + getCurrentDate());
        outboundOrder.setStatus(0);
        outboundOrder.setCreateTime(new Date());
        outboundOrder.setCreateName("admin");
        outboundOrder.setOutboundType("1");
        outboundOrder.setDestination(resources.getDestination());
        outboundOrder.setRequireTime(resources.getRequireTime());
        outboundOrder.setOutboundPolicy(resources.getOutboundPolicy());
        for (TransDao transDao : transDaoList) {
            if (transDao.getWeight()<transDao.getNeedWeight()){
                throw new RuntimeException("需求量不能大于库存");
            }
            List<MaterialDao> materialDaos = materialMapper.selectList(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, transDao.getMaterialCode()));

            if (materialDaos==null||materialDaos.size()<=0){
                throw new RuntimeException("未找到该物料！");
            }
            MaterialDao materialDao =  materialDaos.stream().findFirst().get();
            OutboundOrderDetailDao item = new OutboundOrderDetailDao();
            item.setMaterialCode(materialDao.getMaterialCode());
            item.setWeight(transDao.getWeight());
            item.setMaterialName(materialDao.getMaterialName());
            item.setCreateTime(new Date());
            item.setCreateName(outboundOrder.getCreateName());
            item.setMaterialDescription(materialDao.getSpecs());
            item.setBatchCode(materialDao.getBatchCode());
            item.setEntryTime(materialDao.getEntryTime());
            item.setUnit(materialDao.getUnit());
            item.setVendor(materialDao.getManufacturers());
            item.setIwsOutboundOrderId(outboundOrder.getOutboundOrderNo());
            outboundOrderDetailMapper.insert(item);
        }
        return baseMapper.insert(outboundOrder);
    }

    @Override
    public boolean outBoundOrder() {
        if (baseMapper.outBoundOrder()>0){
            return true;
        }else {
            return false;
        }
    }

    @Override
    public Object updateForStatus(OutboundOrder resources) {
        int i =  baseMapper.updateForStatus(resources);
        return i>0?true:false;
    }

    //查询物料在楼层的库存
    public Double BymaterialCodeGetFloor(String materialCode,String floorId){
        Double weight = materialMapper.BymaterialCodeGetFloor(materialCode,floorId);
        return weight;
    }

    private TransferOutboundDetailDao getTransferOrderDetail(String transferId, OutboundOrder resources) {
        TransferOutboundDetailDao transferOrderDetail = new TransferOutboundDetailDao();
        transferOrderDetail.setTransferCode(transferId);
        transferOrderDetail.setOutboundCode(resources.getOutboundOrderNo());
        transferOrderDetail.setCreateTime(new Date());
        transferOrderDetail.setCreateName("SecurityUtils.getCurrentUsername()");
        return transferOrderDetail;
    }

    // 获取当前日期（格式：yyyyMMdd）
    private static String getCurrentDate() {
        return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
    }

    //获取物料的库存信息
    private Double getInventoryQuantity(String materialCode) {
         return materialMapper.getInventoryQuantity(materialCode);
    }

    private boolean insertDayOutboundOrser(String userName){
        int i = baseMapper.insertDayOutboundOrder(userName);
        return i <= 3;
    }

    private  OutboundOrderDetailDao getOutBoundOrderDetail(MaterialDetailDao materialVo, OutboundOrder outBoundOrder) {
        MaterialDao materialDao = materialMapper.selectList(new LambdaQueryWrapper<MaterialDao>().eq(MaterialDao::getMaterialCode, materialVo.getMaterialCode())).get(0);
        OutboundOrderDetailDao item = new OutboundOrderDetailDao();
        item.setMaterialCode(materialVo.getMaterialCode());
        item.setWeight(materialVo.getUnIssuedWeight());
        item.setMaterialName(materialVo.getMaterialName());
        item.setCreateTime(new Date());
        item.setCreateName(outBoundOrder.getCreateName());
        item.setMaterialDescription(materialDao.getSpecs());
        item.setBatchCode(materialDao.getBatchCode());
        item.setEntryTime(materialDao.getEntryTime());
        item.setUnit(materialDao.getUnit());
        item.setVendor(materialDao.getManufacturers());
        item.setIwsOutboundOrderId(outBoundOrder.getOutboundOrderNo());
        return item;
    }
    //提交审批
//    private void approval( ){
//        //审批流程
//
//    }
}




